package com.zzgc.modules.controller;

import com.zzgc.common.entity.*;
import com.zzgc.common.fliter.Role;
import com.zzgc.common.fliter.StatelessRealm;
import com.zzgc.common.response.HttpStatus;
import com.zzgc.common.response.Result;
import com.zzgc.common.utils.JWTUtil;
import com.zzgc.common.utils.MD5Util;
import com.zzgc.modules.param.AuthUserParam;
import com.zzgc.modules.service.AuthDepartService;
import com.zzgc.modules.service.AuthRoleService;
import com.zzgc.modules.service.AuthUserRoleService;
import com.zzgc.modules.service.AuthUserService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户管理模块
 * @Author:
 * @CreateTime: 2022-11-16  14:19
 * @Description:
 * @Version: 1.0
 */
@RestController
@Api(tags = "用户控制")
@RequestMapping("auth/user")
public class AuthUserController extends BaseController{
    @Autowired
    AuthDepartService departService;

    @PostMapping("login")
    @ApiOperation(value = "用户登陆", notes = "JSON格式数据,传输字段: aAccount/aPassword")
    public Result login(@RequestBody AuthUser authUser) throws Exception {
        // 校验账户与密码, 可能抛出错误, 直接返回前端
        AuthUser user = verifyAccountAndPassword(authUser.getAAccount(), authUser.getAPassword());
        // 生成token并返回
        String tokenStr = null;
        try {
            tokenStr = makeTokenStrAndRecordTime(user);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new RuntimeException("登录异常!");
        }
        Map<String, Object> data = new HashMap<>();
        data.put("token", tokenStr);
        data.put("userId", user.getId()); // 用户id
        data.put("roleName",user.getAName()); // 角色名称
        data.put("userName", user.getAAccount()); // 登录名称
        data.put("bankStatus", user.getABankStatus()); // 用户状态
        data.put("departName", JWTUtil.resolveClaim(tokenStr, "departName")); // 部门名称
        data.put("role", JWTUtil.resolveClaim(tokenStr, "role")); // 角色id
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg(HttpStatus.OK.getReasonPhrase())
                .data(data)
                .build();
    }

    /**
     * 添加token信息
     *
     * @param user
     * @return
     */
    private String makeTokenStrAndRecordTime(AuthUser user) throws Exception {
        // 查询角色信息
        AuthUserRole authUserRole = userRoleService.queryByUserId(user.getId());
        // 查询角色类型
        AuthRole authRole = super.roleService.queryById(authUserRole.getARoleId());
        // 查询部门
        AuthDepart authDepart = departService.queryById(user.getADepartId());
        Map<String, String> payload = new HashMap<>();
        payload.put("userName", user.getAName()); // 角色名称
        payload.put("userId", user.getId() + ""); // 用户Id
        payload.put("departName", authDepart.getAName() == null ? null : authDepart.getAName()); // 部门名称
        payload.put("schoolId", user.getASchoolId() == null ? null : user.getASchoolId() + ""); // 学校id
        payload.put("aDepartId", user.getADepartId() == null ? null : user.getADepartId() + ""); // 部门id
        payload.put("regionId", authDepart.getARegionId() == null ? null : authDepart.getARegionId() + ""); // 区域代码
        payload.put("bankStatus", user.getABankStatus());
        payload.put("role", authUserRole.getARoleId() == null ? null : authUserRole.getARoleId() + "");// 角色id
        // 角色类型
        payload.put("type", Role.getName(authUserRole.getARoleId()));// 用户类型
        // 记录登录时间
        //uUserService.updateUUserLoginTime(user.getUserName(), loginTime);
//        return JWTUtil.getToken(payload,20); 不添加时间默认720分钟
        return JWTUtil.getToken(payload);
    }

    /**
     * 校验用户的登录account与password</br>
     * 若校验通过，返回包含着用户信息的JavaBean对象</br>
     *
     * @param username
     * @param password
     * @return
     */
    private AuthUser verifyAccountAndPassword(String username, String password) {
        // 获取用户信息
        AuthUser authUser = new AuthUser();
        authUser.setAAccount(username);
        authUser.setPageable(PageRequest.of(0, Integer.MAX_VALUE));
        Page<AuthUser> authUsers = userService.queryByPage(authUser);
        //System.out.println(authUsers.getTotalElements());

        if (authUsers.getTotalElements() == 0) {
            throw new RuntimeException(HttpStatus.NOT_REGISTER.value() + "#-#" + HttpStatus.NOT_REGISTER.getReasonPhrase());
        } else if (authUsers.getTotalElements() > 1) {
            throw new RuntimeException(HttpStatus.NOT_REGISTER.value() + "#-#存在多个账户!");
        } else if (!authUsers.getContent().get(0).getAPassword().equals(MD5Util.getMD5PWD(password))) {
            throw new RuntimeException(HttpStatus.USERNAME_OR_PASSWORD_ERROR.value() + "#-#" + HttpStatus.USERNAME_OR_PASSWORD_ERROR.getReasonPhrase());
        }
        return authUsers.getContent().get(0);
    }

    @GetMapping("getList")
    @ApiOperation("查询用户列表")
    public Result getUsers(AuthUser user){
        user.setPageable(PageRequest.of(user.getPage() - 1, user.getSize()));
        if (super.getDepartId() != null){
            user.setADepartId(Long.valueOf(super.getDepartId()));
        }else {
            return Result.builder().code(500).msg("暂无部门信息！").build();
        }
        Page<AuthUser> authUsers = userService.queryByPageSchoolName(user);
        for (AuthUser authUser : authUsers) {
            if (authUser.getAState() == 1) {
                authUser.setAType("主账号");
            }else {
                authUser.setAType("子账号");
            }
        }
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg(HttpStatus.OK.getReasonPhrase())
                .data(authUsers)
                .build();
    }

    @PostMapping("register")
    @ApiOperation("添加学校及用户")
    public Result register(@Validated @RequestBody AuthUserParam authUser, HttpServletRequest request) {
        // 判断是否是县教育局, 只有县教育局才能添加学校
        String userRole = super.getUserRole();
        if (!userRole.equals("4")){
            return Result.builder().code(500).msg("权限不足!").build();
        }
        // 校验手机号和账号, 校验重复值
        List<AuthUser> authUsers = userService.queryAllByNamePwd(authUser.getAAccount(), authUser.getAMobile());
        if (authUsers.size() > 0) { // 用户名已存在
            return Result.builder().code(500).msg("用户名或手机号已占用!").build();
        }
        // 校验部门信息(学校名称)是否重复
        AuthDepart authDepart = new AuthDepart();
        authDepart.setAName(authUser.getDepart().getAName());
        long count = departService.count(authDepart);
        if (count > 0) {
            return Result.builder().code(500).msg("已存在该学校,添加失败!").build();
        }

        // 创建用户, 此方法只能创建学校角色用户, 学校和部门的数据表
        AuthUserParam insert = userService.insert(authUser, request);

        if (insert == null) {
            return Result.builder()
                    .code(HttpStatus.FAILED_OPERATION.value())
                    .msg(HttpStatus.FAILED_OPERATION.getReasonPhrase())
                    .build();
        }
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg(HttpStatus.OK.getReasonPhrase())
                .data(authUser)
                .build();
    }

    @PostMapping("registerUser")
    @ApiOperation("添加学校子用户")
    public Result registerUser(@Validated @RequestBody AuthUserParam authUser) {
        // 判断是否是县教育局, 只有县教育局才能添加学校
        String userRole = super.getUserRole();
        if (!userRole.equals("4")){
            return Result.builder().code(500).msg("权限不足!").build();
        }
        // 校验手机号和账号, 校验重复值
        List<AuthUser> authUsers = userService.queryAllByNamePwd(authUser.getAAccount(), authUser.getAMobile());
        if (authUsers.size() > 0) { // 用户名已存在
            return Result.builder().code(500).msg("用户名或手机号已占用!").build();
        }
        // 根据学校id查询部门及信息
        School school = schoolService.queryById(authUser.getASchoolId());
        // 添加用户
        authUser.setAState(2);
        authUser.setADepartId(school.getSSchoolDepartId());
        // 密码加密
        authUser.setAPassword("123456");
        authUser.setAPassword(MD5Util.getMD5PWD(authUser.getAPassword()));
        authUser.setACreateDate(new Date());
        AuthUserParam authUserParam = userService.insertUser(authUser);
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg(HttpStatus.OK.getReasonPhrase())
                .data(authUserParam)
                .build();
    }

    @GetMapping("reduction")
    @ApiOperation(value = "还原密码", notes = "还原为123456")
    public Result reduction(Long userId){
        AuthUser user = new AuthUser();
        user.setId(userId);
        user.setAPassword(MD5Util.getMD5PWD("123456"));
        AuthUser update = userService.update(user);
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg("还原成功!")
                .data(update)
                .build();
    }

    @PutMapping("editPwd")
    @ApiOperation(value = "修改密码", notes = "JSON格式数据,传输字段(字符串类型): oldPwd/newPwd")
    public Result editPwd(@RequestBody HashMap<String, String> map){
        String oldPwd = map.get("oldPwd");
        String newPwd = map.get("newPwd");
        if (oldPwd == null || "".equals(oldPwd)){
            return Result.builder().code(500).msg("旧密码不能为空!").build();
        }
        if (newPwd == null || "".equals(newPwd)){
            return Result.builder().code(500).msg("新密码不能为空!").build();
        }
        if (newPwd.equals(oldPwd)){
            return Result.builder().code(500).msg("新密码和旧密码不能相同!").build();
        }
        AuthUser user1 = userService.queryById(Long.valueOf(super.getUserId()));
        // 校验账户与密码, 可能抛出错误, 直接返回前端
        AuthUser user = verifyAccountAndPassword(user1.getAAccount(), oldPwd);
        user.setAPassword(MD5Util.getMD5PWD(newPwd));
        AuthUser update = userService.update(user);
        if (update.getAPassword().equals(oldPwd)) {
            return Result.builder().code(500).msg("修改密码失败!").build();
        }
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg("修改密码成功!")
                .build();
    }

    @PutMapping("edit")
    @ApiOperation(value = "修改信息", notes = "修改用户信息")
    public Result edit(@RequestBody AuthUserParam authUser){
        AuthUser user = new AuthUser();
        user.setId(authUser.getId());
        user.setAMobile(authUser.getAMobile());
        user.setAName(authUser.getAName());
        AuthUser update = userService.update(user);
        return Result.builder()
                .code(HttpStatus.OK.value())
                .msg("修改成功!")
                .data(update)
                .build();
    }

    @DeleteMapping("del")
    @ApiOperation(value = "删除用户", notes = "删除子账号")
    public Result del(Long userId){
        AuthUser user = userService.queryById(userId);
        if (user.getAState() ==  1){
            return Result.builder().code(500).msg("该账号为主账号不能删除!").build();
        }else {
            boolean b = userService.deleteById(userId);
            if (b) {
                return Result.builder().code(200).msg("删除成功!").build();
            }
        }
        return Result.builder().code(500).msg("删除失败!").build();
    }
}
